Skip to content

fix(cli): scope Android template's keepDebugSymbols to the debug build type only - #15945

Open
2akouwu wants to merge 1 commit into
tauri-apps:devfrom
2akouwu:fix/issue-15884
Open

fix(cli): scope Android template's keepDebugSymbols to the debug build type only#15945
2akouwu wants to merge 1 commit into
tauri-apps:devfrom
2akouwu:fix/issue-15884

Conversation

@2akouwu

@2akouwu 2akouwu commented Aug 29, 2026

Copy link
Copy Markdown

Root cause

The generated app/build.gradle.kts in the mobile Android template wrote:

buildTypes {
    getByName("debug") {
        ...
        packaging {
            jniLibs.keepDebugSymbols.add("*/arm64-v8a/*.so")
            ...
        }
    }

AGP's Kotlin BuildType DSL (com.android.build.api.dsl.ApplicationBuildType) has no packaging member. Because Kotlin resolves an unmatched receiver against the next enclosing scope, that packaging { ... } call silently binds to the outer android {} extension's packaging property instead of anything debug-specific. The keep-symbols globs therefore applied to every build type, including release:

  1. Release .so files shipped unstripped, since AGP's stripReleaseDebugSymbols task matched the glob and copied the lib verbatim instead of running llvm-strip.
  2. ndk.debugSymbolLevel produced no debug-symbols bundle metadata, because ExtractNativeDebugMetadataTask compares byte lengths against the (no-op) strip output and sees them as already stripped.

Both failures are silent — no warning or error is emitted anywhere in the build.

Why this fix

I used the fix the issue itself verified working (AGP 8.11.0 / Gradle 8.14.3): move the keep-symbols globs out of the buildTypes DSL entirely and apply them through the variant API, which is the only surface that actually scopes a setting to a single build type:

androidComponents {
    onVariants(selector().withBuildType("debug")) { variant ->
        variant.packaging.jniLibs.keepDebugSymbols.add("*/arm64-v8a/*.so")
        ...
    }
}

I considered instead moving the packaging {} call to sit next to compileOptions/buildFeatures inside android {} with some kind of build-type conditional, but the DSL doesn't offer a clean way to conditionally scope glob entries there without re-implementing what androidComponents.onVariants already does — so the variant-API approach is both the smallest change and the technically correct one. I kept the existing {{#each abi-list}} Handlebars loop as-is, just changed the surrounding Kotlin scaffolding, to keep the diff minimal.

The issue also names a second affected template in cargo-mobile2 (templates/platforms/android-studio/app/build.gradle.kts.hbs), but that file lives in the separate tauri-apps/cargo-mobile2 repository and isn't part of this repo, so it's out of scope here.

Testing

Added debug_keep_debug_symbols_is_not_applied_to_every_build_type in crates/tauri-cli/src/mobile/android/project.rs, which loads the real (unrendered) template via include_str! and asserts:

  • the getByName("debug") { ... } block (up to getByName("release")) no longer contains a packaging block, guarding against this mis-scoping regressing, and
  • an androidComponents { ... } block exists that scopes to selector().withBuildType("debug") and contains keepDebugSymbols.

This test fails against the pre-fix template (where packaging/keepDebugSymbols sit inside the debug build type and no androidComponents block exists) and passes with the fix applied. I did not run cargo test in this environment since it requires network access to fetch crate dependencies that isn't available here, but the test only does string slicing/contains checks against a &'static str produced by include_str!, so it doesn't depend on any Android/Gradle toolchain — I traced the logic by hand against both the old and new template content to confirm the assertions land as expected on each.

Fixes #15884.

The generated app/build.gradle.kts placed `packaging { jniLibs.keepDebugSymbols.add(...) }` inside `buildTypes { getByName("debug") { ... } }`. AGP's `BuildType` DSL has no `packaging` block, so Kotlin silently resolved the call against the outer `android {}` extension instead, applying the keep-symbols globs to every build type, including release. This shipped unstripped `.so` files in release builds and made `ndk.debugSymbolLevel` unable to produce debug symbols metadata.

Scope the globs to the debug variant explicitly via `androidComponents { onVariants(selector().withBuildType("debug")) { ... } }`, the only DSL surface that actually restricts this setting to a single build type.

Add a regression test asserting the debug build type block stays free of `packaging`/`keepDebugSymbols` and that they instead live in a debug-scoped `androidComponents` variant block.

Fixes tauri-apps#15884.

Signed-off-by: ulofiai <309826581+ulofiai@users.noreply.github.com>
@2akouwu
2akouwu requested a review from a team as a code owner August 29, 2026 13:00
@Legend-Master Legend-Master added the ai-slop Low effort content, see https://github.com/tauri-apps/tauri?tab=contributing-ov-file#ai-tool-policy label Sep 2, 2026
@Legend-Master

Copy link
Copy Markdown
Contributor

As asked in #15884 (comment), please provide a minimal reproducible example for us to test on

@Legend-Master Legend-Master added the status: needs repro This issue needs to a minimal complete and reproducible example label Sep 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-slop Low effort content, see https://github.com/tauri-apps/tauri?tab=contributing-ov-file#ai-tool-policy status: needs repro This issue needs to a minimal complete and reproducible example

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[bug] Android template's keepDebugSymbols applies to every build type — release .so ships unstripped and ndk.debugSymbolLevel extracts nothing

2 participants